#include "cgzCTcpWS.h"
#include "cgzCThreadPool.h"

cgzCSendWS::cgzCSendWS(
    const int ufd,
    const char *data,
    const int len,
    int t,
    const char *reason)
    : cgzCSendS(ufd)
{

    webscoket_encode_message(data, len, t, false, &m_data, m_len, reason);
}

cgzCSendWS::cgzCSendWS(
    const int ufd,
    const int mid,
    const int len,
    const long cid)
    : cgzCSendS(ufd, mid, len, cid)
{
}

cgzCSendWS::~cgzCSendWS()
{
    free(m_data);
    m_data = nullptr;
    m_len = 0;
    m_sendlen = 0;
}

cgzCRecvWS::cgzCRecvWS(
    const char *data,
    const int len,
    const int ufd,
    const int fd,
    int t)
    : cgzCRecvS(data, len, ufd, fd)
{
    rt = t;
}

cgzCRecvWS::~cgzCRecvWS()
{
}

cgzCTcpWS::cgzCTcpWS(
    cgzCThreadPool *pool,
    const char *name,
    const std::string ip,
    const int port,
    const int cid)
    : cgzCTcpS(pool, name, ip, port, cid)
{
    m_tenum = cgzETask::CTcpWS;
    auto node = malloc(sizeof(cgzCWDecode));
    m_pDecodeWS = new (node) cgzCWDecode();
}

cgzCTcpWS::~cgzCTcpWS()
{
    free(m_pDecodeWS);
    m_pDecodeWS = nullptr;
}

bool cgzCTcpWS::connect(int fd, bool is_hand)
{
    is_hand = false;
    cgzCTcpS::connect(fd, is_hand);
    return true;
}

bool cgzCTcpWS::handshake(cgzCTcpFd *fdinfo)
{
    fdinfo->m_hand = true;
    sendaccept(fdinfo);
    return true;
}

bool cgzCTcpWS::sticking(cgzCTcpFd *fdinfo)
{
    if (!fdinfo->m_hand)
    {
        char tail[4] = {0};
        int used = fdinfo->m_recv.used();
        if (used <= sizeof(tail))
        {
            return false;
        }

        if (tail[0] == '\r' && tail[1] == '\n' && tail[2] == '\r' && tail[3] == '\n')
        {
            std::string request;
            fdinfo->m_recv.read(request);

            std::string ret = websocket_check_handshake(request);
            void *node = malloc(sizeof(cgzCSendWS));
            auto psend = new (node) cgzCSendWS(fdinfo->m_ufd, ret.c_str(), ret.length());
            m_sendqueue.push(psend);
            fdinfo->m_recv.clear();
            std::cout << "recvS handshake:" << ret << std::endl;
        }
        return false;
    }
    cgzCWDecode &de = *m_pDecodeWS;
    while (webscoket_decode_message(fdinfo->m_recv, de))
    {
        if (!decodeProc(fdinfo, de))
        {
            // 接收到完整数据包
            void *node = malloc(sizeof(cgzCRecvWS));
            auto recv = new (node) cgzCRecvWS(de.decode_data, de.decode_len, fdinfo->m_ufd, fdinfo->m_fd, de.rt);
            recv->target = m_cid;
            recv->origin = getId();
            todoret(recv);
        }
        // 重置解码器
        m_pDecodeWS = new (m_pDecodeWS) cgzCWDecode();
    }
    return false;
}

bool cgzCTcpWS::decodeProc(cgzCTcpFd *fdinfo, cgzCWDecode &de)
{
    return false;
}
